﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YourWallet
{
    public class AccountsManagement
    {
        enum Interval { Month, Year }

        List<Transaction> transactionsList = new List<Transaction>();
        List<string> accountsNames = new List<string>();
        string activeAccount = "";
        DateTime activeDate = DateTime.Today;
        Interval activeInterval = Interval.Month;

        public AccountsManagement()
        {
        }

        #region AddTransaction

        public void AddTransactions(List<Transaction> trans)
        {
            transactionsList = trans;
        }

        public void AddExpense(double amount, string category, DateTime date, string note)
        {
            if (activeAccount != "")
            {
                transactionsList.Add(new Transaction(activeAccount, amount, category, date, note, TransactionType.Expense));
            }
        }

        public void AddIncome(double amount, string category, DateTime date, string note)
        {
            if (activeAccount != "")
            {
                transactionsList.Add(new Transaction(activeAccount, amount, category, date, note, TransactionType.Income));
            }
        }

        #endregion

        #region Saldo

        public double GetExpense()
        {
            double expenseAmount = 0;

            foreach (Transaction transaction in transactionsList)
            {
                if (transaction.IsExpense() && isActive(transaction))
                {
                    expenseAmount += transaction.GetAmount();
                }
            }

            return expenseAmount;
        }

        public double GetIncome()
        {
            double incomeAmount = 0;

            foreach (Transaction transaction in transactionsList)
            {
                if (transaction.IsIncome() && isActive(transaction))
                {
                    incomeAmount += transaction.GetAmount();
                }
            }

            return incomeAmount;
        }

        public double GetBalance()
        {
            double balance = 0;

            foreach (Transaction transaction in transactionsList)
            {
                if (isActive(transaction))
                {
                    if (transaction.IsIncome())
                    {
                        balance += transaction.GetAmount();
                    }
                    if (transaction.IsExpense())
                    {
                        balance -= transaction.GetAmount();
                    }
                }
            }

            return balance;
        }

        #endregion

        #region GetNumberOfTransactions

        public int GetNumberOfTransactions()
        {
            int result = 0;

            foreach (Transaction transaction in transactionsList)
            {
                if (isActive(transaction))
                {
                    ++result;
                }
            }    

            return result;
        }

        #endregion

        #region ActivateMonthOrYear

        public void SetActiveMonth()
        {
            activeInterval = Interval.Month;
            activeDate = DateTime.Today;
        }

        public bool IsActiveMonth()
        {
            return activeInterval == Interval.Month;
        }

        public void SetActiveYear()
        {
            activeInterval = Interval.Year;
            activeDate = DateTime.Today;
        }

        public bool IsActiveYear()
        {
            return activeInterval == Interval.Year;
        }

        #endregion

        #region ActivateAccount

        public void AddAccount(string accountName)
        {
            if (!accountsNames.Contains(accountName))
            {
                accountsNames.Add(accountName);
                SetActiveAccount(accountName);
            }
        }

        public bool SetActiveAccount(string activeAccount)
        {
            if(accountsNames.Contains(activeAccount))
            {
                this.activeAccount = activeAccount;
                return true;
            }
            return false;
        }

        public string GetActiveAccount()
        {
            return activeAccount;
        }

        public List<string> GetAccountsNames()
        {
            return accountsNames;
        }

        #endregion

        #region FindTransaction

        private bool isActive(Transaction transaction)
        {
            return ((activeAccount == transaction.GetAccountName())
                        && (IsActiveMonth() && activeDate.Month == transaction.GetDate().Month
                        && (activeDate.Year == transaction.GetDate().Year)
                        || (IsActiveYear() && activeDate.Year == transaction.GetDate().Year)));
        }

        private Transaction FindTransaction(int index)
        {
            int i = 0;
            foreach (Transaction transaction in transactionsList)
            {
                if (isActive(transaction))
                {
                    if (index == i)
                    {
                        return transaction;
                    }
                    ++i;
                }
            }
            return null;
        }

        #endregion

        #region GetParameters

        public List<Transaction> GetAllTransations()
        {
            return transactionsList;
        }

        public double GetTransactionAmount(int index)
        {
            return FindTransaction(index).GetAmount();                            
        }

        public string GetTransactionNote(int index)
        {
            return FindTransaction(index).GetNote();
        }

        public string GetTransactionName(int index)
        {
            return FindTransaction(index).GetName();
        }

        public string GetTransactionCategory(int index)
        {
            return FindTransaction(index).GetCategory();
        }

        public string GetTransactionAccountName(int index)
        {
            return FindTransaction(index).GetAccountName();
        }

        public DateTime GetTransactionDate(int index)
        {
            return FindTransaction(index).GetDate();
        }

        public bool IsIncome(int index)
        {
            return FindTransaction(index).IsIncome();
        }

        public bool IsExpense(int index)
        {
            return FindTransaction(index).IsExpense();
        }

        #endregion

        #region SetParameters

        public void SetTransactionParameters(int index, string accountName, double amount, string category,
            DateTime date, string note, TransactionType type)
        {
            FindTransaction(index).SetParameters(accountName, amount, category, date, note, type);
        }

        public void SetTransactionAmount(int index, double amount)
        {
            FindTransaction(index).SetAmount(amount);
        }

        public void SetTransactionNote(int index, string note)
        {
            FindTransaction(index).SetNote(note);
        }

        public void SetTransactionCategory(int index, string category)
        {
            FindTransaction(index).SetCategory(category);
        }

        public void SetTransactionAccountName(int index, string accountName)
        {
            if (accountsNames.Contains(accountName))
            {
                FindTransaction(index).SetAccountName(accountName);
            }
        }

        public void SetTransactionDate(int index, DateTime date)
        {
            FindTransaction(index).SetDate(date);
        }

        public void SetTransactionType(int index, TransactionType type)
        {
            FindTransaction(index).SetType(type);
        }

        public void SetActiveDate(DateTime date)
        {
            activeDate = date;
        }

        #endregion

        #region DeleteTransaction

        public void DeleteTransaction(int index)
        {
            transactionsList.Remove(FindTransaction(index));
        }

        #endregion

        #region SelectionDate

        public DateTime GetActiveDate()
        {
            return activeDate;
        }

        public void IncreaseDate()
        {
            if (Interval.Month == activeInterval)
            {
                int month = activeDate.Month;
                int year = activeDate.Year;

                if (month < 12)
                {
                    month++;
                }
                else
                {
                    month = 1;
                    year++;
                }
                activeDate = new DateTime(year, month, 1);
            }
            else if (Interval.Year == activeInterval)
            {
                activeDate = new DateTime(activeDate.Year + 1, activeDate.Month, 1);
            }
        }

        public void DecreaseDate()
        {
            if (Interval.Month == activeInterval)
            {
                int month = activeDate.Month;
                int year = activeDate.Year;

                if (month > 1)
                {
                    month--;
                }
                else
                {
                    month = 12;
                    year--;
                }
                activeDate = new DateTime(year, month, 1);

            }
            else if (Interval.Year == activeInterval)
            {
                activeDate = new DateTime(activeDate.Year - 1, activeDate.Month, 1);
            }
        }

        #endregion
    }
}
